package com.github.easycaptcha.impl;

import com.github.easycaptcha.AbstractArithmeticCaptcha;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;

/**
 * png格式验证码
 */
public class ArithmeticCaptcha extends AbstractArithmeticCaptcha {

  public ArithmeticCaptcha() {
  }

  public ArithmeticCaptcha(int width, int height) {
    this();
    setWidth(width);
    setHeight(height);
  }

  public ArithmeticCaptcha(int width, int height, int len) {
    this(width, height);
    setLen(len);
  }

  public ArithmeticCaptcha(int width, int height, int len, Font font) {
    this(width, height, len);
    setFont(font);
  }

  /**
   * 生成验证码
   *
   * @param out 输出流
   * @return 是否成功
   */
  @Override
  public boolean out(OutputStream out) {
    checkAlpha();
    return graphicsImage(getArithmeticString().toCharArray(), out);
  }

  @Override
  public String toBase64() {
    return toBase64("data:image/png;base64,");
  }

  /**
   * 生成验证码图形
   *
   * @param strs 验证码
   * @param out  输出流
   * @return boolean
   */
  private boolean graphicsImage(char[] strs, OutputStream out) {
    try {
      BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2d = (Graphics2D) bi.getGraphics();
      // 填充背景
      // g2d.setColor(Color.WHITE);
      // g2d.fillRect(0, 0, width, height);
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
      // 抗锯齿
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      // 画干扰圆
      drawOval(2, g2d);
      // 画字符串
      g2d.setFont(getFont());
      FontMetrics fontMetrics = g2d.getFontMetrics();
      int fW = width / strs.length;  // 每一个字符所占的宽度
      int fSp = (fW - (int) fontMetrics.getStringBounds("8", g2d).getWidth()) / 2;  // 字符的左右边距
      for (int i = 0; i < strs.length; i++) {
        g2d.setColor(color());
        int fY = height - ((height - (int) fontMetrics.getStringBounds(String.valueOf(strs[i]), g2d).getHeight()) >> 1);  // 文字的纵坐标
        g2d.drawString(String.valueOf(strs[i]), i * fW + fSp + 3, fY - 3);
      }
      g2d.dispose();
      ImageIO.write(bi, "png", out);
      out.flush();
      return true;
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        out.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return false;
  }
}